package org.example.backend.Module.System.User.Service.Impl;

import cn.hutool.core.bean.BeanUtil;
import lombok.extern.slf4j.Slf4j;
import org.example.backend.Base.Exception.ServiceException;
import org.example.backend.Base.Response.StatusCode;
import org.example.backend.Base.Util.JWT;
import org.example.backend.Module.System.User.Mapper.UserMapper;
import org.example.backend.Module.System.User.Pojo.Entity.User;
import org.example.backend.Module.System.User.Pojo.DTO.UserLogin;
import org.example.backend.Module.System.User.Pojo.Entity.MyUserDetails;
import org.example.backend.Module.System.User.Pojo.Vo.UserVo;
import org.example.backend.Module.System.User.Service.UserService;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;

@Service
@Slf4j
public class UserServiceImpl implements UserService {

    @Resource
    private JWT jwt;

    @Resource
    private RedisTemplate<Object, Object> redisTemplate;

    @Resource
    private AuthenticationManager authenticationManager;

    @Resource
    private UserMapper userMapper;

    @Override
    public UserLogin login(String username, String password) {
        Authentication auth = this.authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password));

        if(auth == null) throw new ServiceException(StatusCode.PASSWORD_ERROR);

        MyUserDetails userDetails = (MyUserDetails) auth.getPrincipal();

        User user = userDetails.getUser();

        Map<String, Object> payload = new HashMap<>();
        payload.put("uid", user.getId());

        this.redisTemplate.opsForValue().set("user-token-" + user.getId(), userDetails);

        return new UserLogin(jwt.create(null, payload), BeanUtil.copyProperties(user, UserVo.class));
    }

    @Override
    public UserVo myInfo() {
        SecurityContext context = SecurityContextHolder.getContext();

        MyUserDetails userDetails = (MyUserDetails) context.getAuthentication().getPrincipal();

        return BeanUtil.copyProperties(userDetails.getUser(), UserVo.class);
    }

    @Override
    public User addOrUpdateUser(User user) {
        this.userMapper.insertOrUpdate(user);

        return user;
    }

    @Override
    public UserVo getById(Long id) {
        User user = this.userMapper.selectById(id);

        return user != null ? BeanUtil.copyProperties(user, UserVo.class) : null;
    }


}
